﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace MyTetris
{
    /// <summary>
    /// 游戏引擎（控制核心）
    /// </summary>
    public class GameEngine
    {
        //每个小方块的边长（像素为单位）
        public const int SQUARE_WIDTH = 25;
        //游戏区域的宽度（单个小方块为单位）
        public const int FIELD_W = 12;
        //游戏区域的高度（单个小方块为单位）
        public const int FIELD_H = 20;
        //定义一个游戏速度（数值越大，速度越慢）
        private int speed = 30;
        //游戏矩阵，1代表有方块，0代表没有
        public int[,] matrix = null;

        private Timer timerEngine = new Timer();//定时器
        private static GameEngine instance = null;//私有静态单例
        private List<Square> metaSquares = new List<Square>();//游戏区域中小方块的集合

        public static bool isRPG = true;
        public BaseBlock CurrentBlock = null;

        //定义事件用以通知是否需要重新绘制
        public event Action InvalidteFieldEvent;

        //游戏区域的宽度（以像素为单位）
        public int FieldIndexWidth
        {
            get
            {
                return SQUARE_WIDTH * FIELD_W;
            }
        }
        //游戏区域的高度（以像素为单位）
        public int FieldIndexHeight
        {
            get
            {
                return SQUARE_WIDTH * FIELD_H;
            }
        }

        public static GameEngine Instance//单例模式
        {
            get
            {
                if (instance == null)
                    instance = new GameEngine();
                return instance;
            }
        }
        
        private GameEngine()
        {
            matrix = new int[FIELD_H, FIELD_W];
            timerEngine.Interval = 10;
            timerEngine.Elapsed += new ElapsedEventHandler(timerEngine_Elapsed);
            RestartGame();
        }

        private void AddSquares(BaseBlock block)
        {
            metaSquares.AddRange(block.Squares);
        }

        //判断游戏是否结束
        public bool _IsSelfGameOver = false;
        public bool IsSelfGameOver
        {
            set
            {
                _IsSelfGameOver = value;
                timerEngine.Enabled = _IsSelfGameOver ? false : true;
                if (_IsSelfGameOver)
                {

                    SetDisableColor();
                }
            }
            get
            {
                return _IsSelfGameOver;
            }
        }
        public void SetDisableColor()
        {
            foreach (var s in metaSquares)
            {
                s.FillColor = Color.White;
            }
        }

        //重新开始游戏
        public void RestartGame()
        {
            timerEngine.Enabled = true;
            NewBlock();
        }
        public void NewBlock()
        {
            CurrentBlock = BlockFactory.Create();
            AddSquares(CurrentBlock);
            

        }
        
        private int speedTimerTag;
        void timerEngine_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (speedTimerTag + 1 >= int.MaxValue)
                speedTimerTag = 0;
            if (speedTimerTag % speed == 0)//控制方块下移速度
            {
                if (CurrentBlock != null)
                {
                    CurrentBlock.MoveDown();
                }
            }
            speedTimerTag++;
            if (InvalidteFieldEvent != null)
                InvalidteFieldEvent();
        }
        //绘制所有小方块
        public void DrawAllSquares(Graphics g)
        {
            foreach(var s in metaSquares)
            {
                s.Draw(g);
            }
        }


        private int _Score;
        public int Score //得分
        {
            set
            {
                _Score = value;
            }
            get
            {
                return _Score;
            }
        }

        public void RemoveLine(int i)
        {
            //Matrix的行i全部设为0
            for (int a = 0; a < FIELD_W; a++)
            {
                matrix[i, a] = 0;
            }
            //去除行i的全部元素
            metaSquares = metaSquares.FindAll(s => s.IndexTop != i);
            //行i上方的所有元素下移
            var aboveSquares = metaSquares.FindAll(s =>
            {
                return (s.IndexTop < i);
            });
            //按行号降序排序
            var orderedAbove = aboveSquares.OrderByDescending<Square, int>(s =>
            {
                return s.IndexTop;
            });
            foreach (var square in orderedAbove)
            {
                square.MoveDown();
                matrix[square.IndexTop, square.IndexLeft] = 1;
            }

        }
        public void CheckLine()
        {
            //逐行检测是否有满行
            int fullRowsCount = 0;
            for (int i = 0; i < FIELD_H; i++)
            {
                bool tag = true;
                for (int j = 0; j < FIELD_W; j++)
                {
                    if (matrix[i, j] == 0)
                    {
                        tag = false;
                        break;
                    }
                }
                if (tag)//如果满行
                {
                    Score++;
                    fullRowsCount++;
                    RemoveLine(i);
                }
            }
        }
        
        private void ClearMatrix()
        {
            for (int i = 0; i < FIELD_H; i++)
                for (int j = 0; j < FIELD_W; j++)
                    matrix[i, j] = 0;
        }
        public void RemoveLastLine()
        {
            RemoveLine(FIELD_H - 1);
        }
        
    }
}
 